package com.yt.sys.api.client;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.yt.common.constant.Result;
import com.yt.sys.common.config.AlipayConfig;
import com.yt.sys.models.service.IPaymentOrderService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.text.DecimalFormat;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 账单支付宝支付接口控制器
 * 专门用于处理账单统一结算的支付宝支付功能
 */
@Slf4j
@RestController
@RequestMapping("/api/bill-alipay")
@Api(value = "BillAlipayController", tags = "账单支付宝支付接口")
public class BillAlipayController {

    @Resource
    private AlipayConfig alipayConfig;

    // 注入账单服务
    @DubboReference
    private com.yt.phone.models.service.IBillService billService;
    
    // 注入用户账单关联服务
    @DubboReference
    private com.yt.phone.models.service.IPhoneBillService phoneBillService;
    
    // 注入支付订单服务
    @DubboReference
    private IPaymentOrderService paymentOrderService;

    /**
     * 发起账单统一结算支付 (支持GET和POST请求)
     *
     * @param userId      用户ID
     * @param totalAmount 订单总金额
     * @param subject     订单标题
     * @param body        订单描述
     * @param httpRequest HTTP请求对象
     * @return 支付页面表单
     */
    @ApiOperation("发起账单统一结算支付")
    @RequestMapping(value = "/bill-pay", method = {RequestMethod.GET, RequestMethod.POST}, produces = "text/html")
    public String billPay(
            @RequestParam(required = false) Long userId,
            @RequestParam(required = false) Double totalAmount,
            @RequestParam(required = false) String subject,
            @RequestParam(required = false) String body,
            HttpServletRequest httpRequest) {
        try {
            // 如果通过@RequestParam没有获取到参数，则尝试从request中获取
            if (userId == null) {
                String userIdStr = httpRequest.getParameter("userId");
                if (userIdStr != null && !userIdStr.isEmpty()) {
                    userId = Long.valueOf(userIdStr);
                }
            }
            if (totalAmount == null) {
                String totalAmountStr = httpRequest.getParameter("totalAmount");
                if (totalAmountStr != null && !totalAmountStr.isEmpty()) {
                    totalAmount = Double.valueOf(totalAmountStr);
                }
            }
            if (subject == null || subject.isEmpty()) {
                subject = httpRequest.getParameter("subject");
            }
            if (body == null || body.isEmpty()) {
                body = httpRequest.getParameter("body");
            }
            
            // 参数验证
            if (userId == null || totalAmount == null || subject == null || subject.isEmpty() || body == null || body.isEmpty()) {
                log.error("缺少必要参数: userId={}, totalAmount={}, subject={}, body={}", userId, totalAmount, subject, body);
                return "缺少必要参数";
            }
            
            // 格式化金额，确保为字符串且保留两位小数
            DecimalFormat df = new DecimalFormat("0.00");
            String formattedAmount = df.format(totalAmount);
            
            // 创建支付订单，获取系统生成的订单号
            String outTradeNo = paymentOrderService.createPaymentOrder(userId, totalAmount);
            log.info("为用户ID {} 创建账单支付订单，订单号: {}", userId, outTradeNo);
            
            // 使用自定义的支付方法，不修改全局配置
            String result = pay(outTradeNo, formattedAmount, subject, body);
            return result;
        } catch (NumberFormatException e) {
            log.error("参数格式错误", e);
            return "参数格式错误";
        } catch (Exception e) {
            log.error("账单支付请求异常", e);
            return "账单支付请求失败";
        }
    }
    
    /**
     * 自定义支付方法，使用特定的回调URL
     *
     * @param outTradeNo  商户订单号
     * @param totalAmount 订单总金额
     * @param subject     订单标题
     * @param body        订单描述
     * @return 支付页面表单
     * @throws AlipayApiException 支付宝API异常
     */
    public String pay(String outTradeNo, String totalAmount, String subject, String body) throws AlipayApiException {
        // 根据支付宝的配置生成一个支付客户端
        AlipayClient alipayClient = new DefaultAlipayClient(
                alipayConfig.getGatewayUrl(),
                alipayConfig.getAppId(),
                alipayConfig.getMerchantPrivateKey(),
                "json",
                alipayConfig.getCharset(),
                alipayConfig.getAlipayPublicKey(),
                alipayConfig.getSignType());

        // 创建一个支付请求，并设置请求参数
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        
        // 设置特定的回调URL
        String returnUrl = alipayConfig.getReturnUrl();
        String notifyUrl = alipayConfig.getNotifyUrl().replace("/alipay/notify", "/bill-alipay/bill-notify");
        
        alipayRequest.setReturnUrl(returnUrl);
        alipayRequest.setNotifyUrl(notifyUrl);

        // 构造业务参数时确保格式正确
        StringBuilder bizContent = new StringBuilder();
        bizContent.append("{")
                  .append("\"out_trade_no\":\"").append(outTradeNo).append("\",")
                  .append("\"total_amount\":\"").append(totalAmount).append("\",")
                  .append("\"subject\":\"").append(subject).append("\",")
                  .append("\"body\":\"").append(body).append("\",")
                  .append("\"timeout_express\":\"").append(alipayConfig.getTimeout()).append("\",")
                  .append("\"product_code\":\"FAST_INSTANT_TRADE_PAY\"")
                  .append("}");

        alipayRequest.setBizContent(bizContent.toString());
                
        String result = alipayClient.pageExecute(alipayRequest, "POST").getBody();
        //会收到支付宝的响应，响应的是一个页面，只要浏览器显示这个页面，就会自动来到支付宝的收银台页面
        log.info("支付宝的响应：" + result);
        return result;
    }
    
    /**
     * 账单支付支付宝异步通知接口
     *
     * @param params 异步通知参数
     * @return 处理结果
     */
    @ApiOperation("账单支付支付宝异步通知接口")
    @PostMapping("/bill-notify")
    public String billNotify(@RequestParam Map<String, String> params) {
        log.info("收到账单支付支付宝异步通知: {}", params);
        
        try {
            // 1. 验证签名
            boolean verifyResult = com.yt.sys.common.utils.AlipaySignatureUtil.verifySignature(params);
            if (!verifyResult) {
                log.error("支付宝异步通知签名验证失败: {}", params);
                return "fail";
            }
            
            // 2. 处理业务逻辑
            // 获取商户订单号
            String outTradeNo = params.get("out_trade_no");
            // 获取交易状态
            String tradeStatus = params.get("trade_status");
            
            // 3. 更新订单状态
            if ("TRADE_SUCCESS".equals(tradeStatus) || "TRADE_FINISHED".equals(tradeStatus)) {
                // 根据订单号查询支付订单
                com.yt.sys.models.entity.PaymentOrder paymentOrder = paymentOrderService.getPaymentOrderByOrderNo(outTradeNo);
                if (paymentOrder == null) {
                    log.error("未找到支付订单，订单号: {}", outTradeNo);
                    return "fail";
                }
                
                // 获取用户ID和金额
                Long userId = paymentOrder.getUserId();
                Double amount = paymentOrder.getAmount();
                
                log.info("账单支付成功，用户ID: {}, 订单号: {}, 支付金额: {}", userId, outTradeNo, amount);
                
                // 更新支付订单状态为已支付
                boolean updateResult = paymentOrderService.updatePaymentOrderStatus(outTradeNo, 1);
                
                if (!updateResult) {
                    log.error("支付订单状态更新失败，订单号: {}", outTradeNo);
                    return "fail";
                }
                
                // 查询该用户所有未计费的账单并更新为已计费状态
                // 使用status=0来筛选未计费账单，而不是pay_status
                List<com.yt.phone.models.dto.BillDTO> unpaidBills = billService.getBillListByStatus(0); // 0表示未计费
                // 查询所有用户账单关联记录
                List<com.yt.phone.models.dto.PhoneBillDTO> phoneBills = phoneBillService.selectList(new com.baomidou.mybatisplus.mapper.EntityWrapper<>());
                
                // 过滤出当前用户的未计费账单
                List<com.yt.phone.models.dto.BillDTO> currentUserUnpaidBills = unpaidBills.stream()
                        .filter(bill -> {
                            // 查找该账单是否属于当前用户
                            return phoneBills.stream()
                                .anyMatch(pb -> 
                                    pb.getBillId() != null && 
                                    pb.getBillId().equals(bill.getBillId()) && 
                                    pb.getUserId() != null && 
                                    pb.getUserId().equals(userId));
                        })
                        .collect(Collectors.toList());
                
                log.info("找到用户 {} 的未计费账单 {} 个", userId, currentUserUnpaidBills.size());
                
                // 更新这些账单的状态为已计费
                int updatedCount = 0;
                for (com.yt.phone.models.dto.BillDTO bill : currentUserUnpaidBills) {
                    // 更新账单为已计费状态（状态1表示已计费）
                    // 不再将支付金额添加到用户余额中
                    boolean billUpdateResult = billService.updatePayInfo(
                            bill.getBillId(), 
                            bill.getBill() != null ? Math.abs(bill.getBill()) : 0.0, 
                            "支付宝", 
                            1);
                    if (!billUpdateResult) {
                        log.error("账单状态更新失败，账单ID: {}", bill.getBillId());
                    } else {
                        log.info("账单状态更新成功，账单ID: {}", bill.getBillId());
                        updatedCount++;
                    }
                }
                
                log.info("账单支付处理成功，订单号: {}, 用户ID: {}, 支付金额: {}, 支付方式: 支付宝, 更新账单数: {}/{}", 
                        outTradeNo, userId, amount, currentUserUnpaidBills.size(), updatedCount);
                return "success";
            }
        } catch (Exception e) {
            log.error("处理账单支付支付宝异步通知异常", e);
            return "fail";
        }
        
        return "success";
    }
}